/**
 *  The Yz.Upload prototype
 *
 */
(function(Yz) {
    if ( typeof(Yz) != "function" ) {
        throw "Failed to identify the root Yz object";
    }

    // prevent multiple execution
    if ('Upload' in Yz) {
        return;
    }

    Yz.Upload = function(elName)
    {
        return this.init(elName);
    };


    /****************************
     *      Implementation      *
     ****************************/


    /**
     *  @access private
     *  @var Object/Hash { formName: handler }
     */
    Yz.Upload.handlers = {};
    /**
     *  @var object {theDiv, theForm, theInput}
     */
    Yz.Upload.form = null;
    Yz.Upload.timer = false;
    Yz.Upload.currentHandler = false;

    /** Create instance of Yz.Upload for the element elName or use the one already created
     *  @param string elName [REQUIRED]
     *  @return handler
     */
    Yz.Upload.createUpload = function(elName)
    {
        var handler = Yz.Upload.handlers[elName];
        if (! handler) {
            handler = new Yz.Upload(elName);
            Yz.Upload.handlers[elName] = handler;
        }
        return handler;
    }

    /** call this static method when file uploaded successfully
     *  @param string formName
     *  @param string message
     */
    Yz.Upload.uploadComplete = function(successCallback)
    {
        var handler = Yz.Upload.currentHandler;
        if (! handler) {
            throw "Invalid handler ID";
        }
        handler.complete(successCallback);
        return Yz.Upload;
    }
    Yz.Upload.uploadFailed = function(failureCallback)
    {
        var handler = Yz.Upload.currentHandler;
        if (! handler) {
            throw "Invalid handler ID";
        }
        handler.fail(failureCallback);
        return Yz.Upload;
    }

    /**
     *  @return object {theDiv, theForm, theInput}
     */
    Yz.Upload.createForm = function()
    {
        if (! Yz.Upload.form) {
            var div = document.createElement("DIV");
            div.innerHTML = "<form enctype='multipart/form-data' action='' method='POST' target='YzUploadFrame'>"
                + "<input type='file' name='theUpload' />"
                + "</form>"
                + "<iframe name='YzUploadFrame' id='YzUploadFrame' src='about:blank'"
                + ' style="border: 1px solid red; width: 100px; height: 100px"'
                + "></iframe>"
                ;
            Yz.Upload.form = {
                theDiv: div,
                theForm: div.getElementsByTagName("FORM")[0],
                theInput: div.getElementsByTagName("INPUT")[0]
            };
        }
        return Yz.Upload.form;
    }



    Yz.Upload.prototype = {
        sourceDiv: false,
        sourceInput: false,
        form: false,
        elName: false,
        uploadAction: false,
        deleteAction: false,

        /**
         *  the modified constructor: multiton, by form name
         *  Arguments: object {formName, inputName, success, failure}
         */
        init: function(elName)
        {
            this.sourceDiv = document.getElementById('yz-upload-' + elName);
            if (! this.sourceDiv) {
                throw "Source DIV element not found";
            }
            this.sourceInput = this.sourceDiv.getElementsByTagName("INPUT")[0];
            if (! this.sourceInput) {
                throw "Source INPUT element not found";
            }
            this.elName = elName;
            return this;
        } ,

        setUploadAction: function(uploadAction)
        {
            this.uploadAction = uploadAction;
            return this;
        },

        setDeleteAction: function(deleteAction)
        {
            this.deleteAction = deleteAction;
            return this;
        },

        /**
         *  Show a dialog with the form and iframe
         *  @access private
         *  @param i18n {}
         *  @return Yz.Upload
         */
        showDialog: function(i18n)
        {
            console.log("upload: showDialog");
            var form = this.form = Yz.Upload.createForm();
            console.log("input:" + this.form.theInput);

            form.theInput.value = "";
            form.theForm.setAttribute("action", this.uploadAction);

            var self = this;

            Yz.jqueryui(function(){
                var buttons = {};
                buttons[i18n.upload] = function() { self.submit(); }
                buttons[i18n.cancel] = function() { $(this).dialog("close"); }
                $(form.theDiv).dialog({
                    modal: true,
                    title: i18n.title,
                    buttons: buttons
                });
            });
            return this;
        } ,

        /**
        *  the "user" function
        *
        */
        submit: function()
        {
            console.log("submit action:" + this.form.theForm.action);
            if ( this.form.theInput.value ) {
                this.startTimer()
                    && this.form.theForm.submit();
            } else {
                Yz.Alert( "Файл не выбран" );
            }
            return false;
        } ,

        /**
         *  @access private
         */
        startTimer: function()
        {
            console.log("start timer: " + Yz.Upload.timer);
            if ( false !== Yz.Upload.timer ) {
                // prevent multiple simultaneous file uploads
                Yz.Alert( "Подождите, идёт загрузка..." );
                return false;
            }
            Yz.Upload.timer = setTimeout( this.timeout, 60000 );
            Yz.Upload.currentHandler = this;
            Yz.block();
            return true;
        } ,

        /**
         *  @access private
         */
        timeout: function()
        {
            Yz.Alert( "Upload timeout" );
            return Yz.Upload.currentHandler.done();
        } ,

        /**
         *  @access private
         */
        complete: function( successCallback )
        {
            console.log("upload: complete");
            successCallback.call(this);
            return this.done();
        } ,

        /**
         *  @access private
         */
        fail: function( failureCallback )
        {
            console.log("upload: fail");
            failureCallback.call(this);
            //Yz.Alert( errorMessage );
            return this.done();
        } ,

        /**
         *  @access private
         */
        done: function()
        {
            console.log("upload done");
            if ( false !== Yz.Upload.timer ) {
                clearTimeout( Yz.Upload.timer );
            }
            Yz.Upload.currentHandler = false;
            Yz.Upload.timer = false;
            Yz.unblock();
            //Yz.Alert("Done");
            return this;
        }
    } // end prototype

})(window.Yz);

